#include "ScrollBar.h"
namespace NBGUI
{
	ScrollBar::ScrollBar(GUIDrawer* drawer,  const char* name, const char* eleText, int eleType, Rect& _rect, float _occ):
		ElementNode(drawer, name,eleText,eleType,_rect),Grid3x3(2,2,64,64),occupy(_occ),currentPos(0)
{

	uv[0] = vec2f(256.0f/512,0);
	uv[1] = vec2f(256.0f/512,64.0f/512);
	uv[2] = vec2f(320.0f/512,64.0f/512);
	uv[3] = vec2f(320.0f/512,0);

	uv[4] = vec2f(320.0f/512,0);
	uv[5] = vec2f(320.0f/512,64.0f/512);
	uv[6] = vec2f(384.0f/512,64.0f/512);
	uv[7] = vec2f(384.0f/512,0);

	uv_arrow[0] = vec2f(384.0f/512,0);
	uv_arrow[1] = vec2f(384.0f/512,64.0f/512);
	uv_arrow[2] = vec2f(448.0f/512,64.0f/512);
	uv_arrow[3] = vec2f(448.0f/512,0);

	uv_arrow[4] = vec2f(448.0f/512,0);
	uv_arrow[5] = vec2f(448.0f/512,64.0f/512);
	uv_arrow[6] = vec2f(512.0f/512,64.0f/512);
	uv_arrow[7] = vec2f(512.0f/512,0);

	Rect upRect;
	upRect.x = rect.x;
	upRect.y = rect.y - 20;
	upRect.w = upRect.h = 20;
	
	upArrow = new Button(drawer,(std::string(name) + "_UpArrow").c_str(),"",uv_arrow,BUTTON,upRect);
	Handler h;
	h.name = name;
	h.eventType = MOUSE_BUTTON_RELEASE;
	h.funcName = "refreshPos";
	info i;
	i.f = -0.1f;
	h.parameters.push_back(i);
	upArrow->add(h);

	Rect downRect;
	downRect.x = rect.x;
	downRect.y = rect.y + rect.h;
	downRect.w = downRect.h = 20;
	downArrow = new Button(drawer,(std::string(name) + "_DownArrow").c_str(),"",&uv_arrow[4],BUTTON,downRect);
	h.parameters.front().f = 0.1f;
	h.eventType = MOUSE_BUTTON_RELEASE;
	downArrow->add(h);
}

ScrollBar::~ScrollBar()
{
	delete upArrow;
	delete downArrow;
}

void ScrollBar::buildVI( std::vector<Vertex>* vertices, std::vector<unsigned int>* indices,unsigned int screenWidth, unsigned int screenHeight )
{
	startIndex = indices->size();
	//background
	backVertexOffset = vertices->size();
	for (int i = 0; i < 9; ++i)
	{
		Rect gridRect = grid[i];
		float left, right, top, bottom;



		if(i == TOPRIGHT || i == MIDRIGHT || i == BOTTOMRIGHT)
		{
			left = (-(float)screenWidth / 2) + (float)rect.x + rect.w - edgeWidth;
		}
		else
		{
			left = (-(float)screenWidth / 2) + (float)rect.x + (float)gridRect.x ;
		}



		if(i == TOPMID || i == MIDMID || i == BOTTOMMID)
		{
			//mid grid , draw as the xml says
			right = left + rect.w - 2 * edgeWidth;
		}
		else
		{
			right = left + (float)gridRect.w ;
		}

		if (i > MIDRIGHT && i <= BOTTOMRIGHT)
		{
			//bottom 3 grid
			top = (float)screenHeight / 2 - (float)rect.y - (rect.h - edgeHeight);
		}
		else
		{
			top = (float)screenHeight / 2 - (float)rect.y -  (float)gridRect.y;
		}

		if(i > TOPRIGHT && i <= MIDRIGHT)
		{
			bottom = top - (rect.h - 2 * edgeHeight) ;
		}
		else
		{
			bottom = top - (float)gridRect.h ;
		}



		Vertex eleVertices[4];
		unsigned int current = vertices->size();
		unsigned int eleIndices[6]={0,1,2,0,2,3};


		eleVertices[0].pos = vec3f(left, top, 0.0f);  // Top left.
		eleVertices[0].coord = uv[0];
		eleVertices[0].coord.x += gridRect.x/512.0f;
		eleVertices[0].coord.y += gridRect.y/512.0f;

		eleVertices[1].pos = vec3f(left, bottom, 0.0f);  // Bottom left.
		eleVertices[1].coord = eleVertices[0].coord;
		eleVertices[1].coord.y += gridRect.h/512.0f;

		eleVertices[2].pos = vec3f(right, bottom, 0.0f);  // Bottom right.
		eleVertices[2].coord = eleVertices[0].coord;
		eleVertices[2].coord.x += gridRect.w/512.0f;
		eleVertices[2].coord.y += gridRect.h/512.0f;

		eleVertices[3].pos = vec3f(right, top, 0.0f);  // Top right.
		eleVertices[3].coord = eleVertices[0].coord;
		eleVertices[3].coord.x += gridRect.w/512.0f;

		for (int i = 0; i < 4; ++i)
		{
			vertices->push_back(eleVertices[i]);
		}



		for (int i = 0; i  < 6; ++i)
		{
			indices->push_back(current + eleIndices[i]);
		}

		indexLen += 6;
	}
	//////////////////////////////////////////////////////////////////////////
	//front ground (the progress)
	float newH = rect.h * occupy;

	float newY = rect.y + currentPos * newH;

	frontVertexOffset = vertices->size();
	for (int i = 0; i < 9; ++i)
	{
		Rect gridRect = grid[i];
		float left, right, top, bottom;



		if(i == TOPRIGHT || i == MIDRIGHT || i == BOTTOMRIGHT)
		{
			left = (-(float)screenWidth / 2) + (float)rect.x + rect.w - edgeWidth;
		}
		else
		{
			left = (-(float)screenWidth / 2) + (float)rect.x + (float)gridRect.x ;
		}



		if(i == TOPMID || i == MIDMID || i == BOTTOMMID)
		{
			//mid grid , draw as the xml says
			right = left + rect.w- 2 * edgeWidth;
		}
		else
		{
			right = left + (float)gridRect.w ;
		}

		if (i > MIDRIGHT && i <= BOTTOMRIGHT)
		{
			//bottom 3 grid
			top = (float)screenHeight / 2 - (float)newY - (newH - edgeHeight);
		}
		else
		{
			top = (float)screenHeight / 2 - (float)newY -  (float)gridRect.y;
		}

		if(i > TOPRIGHT && i <= MIDRIGHT)
		{
			bottom = top - (newH - 2 * edgeHeight) ;
		}
		else
		{
			bottom = top - (float)gridRect.h ;
		}



		Vertex eleVertices[4];
		unsigned int currentVertexOffset = vertices->size();
		unsigned int eleIndices[6]={0,1,2,0,2,3};


		eleVertices[0].pos = vec3f(left, top, 0.0f);  // Top left.
		eleVertices[0].coord = uv[4];
		eleVertices[0].coord.x += gridRect.x/512.0f;
		eleVertices[0].coord.y += gridRect.y/512.0f;

		eleVertices[1].pos = vec3f(left, bottom, 0.0f);  // Bottom left.
		eleVertices[1].coord = eleVertices[0].coord;
		eleVertices[1].coord.y += gridRect.h/512.0f;

		eleVertices[2].pos = vec3f(right, bottom, 0.0f);  // Bottom right.
		eleVertices[2].coord = eleVertices[0].coord;
		eleVertices[2].coord.x += gridRect.w/512.0f;
		eleVertices[2].coord.y += gridRect.h/512.0f;

		eleVertices[3].pos = vec3f(right, top, 0.0f);  // Top right.
		eleVertices[3].coord = eleVertices[0].coord;
		eleVertices[3].coord.x += gridRect.w/512.0f;

		for (int i = 0; i < 4; ++i)
		{
			vertices->push_back(eleVertices[i]);
		}



		for (int i = 0; i  < 6; ++i)
		{
			indices->push_back(currentVertexOffset + eleIndices[i]);
		}

		indexLen += 6;
	}

	//////////////////////////////////////////////////////////////////////////
	upArrow->buildVI(vertices,indices,screenWidth,screenHeight);
	downArrow->buildVI(vertices,indices,screenWidth,screenHeight);
}


void ScrollBar::draw()
{
	if(hide)
		return;
	pDrawer->pRenderer->applyTexture(0);
	pDrawer->pRenderer->drawIndexed(startIndex,indexLen,pDrawer->vboId,pDrawer->iboId);

	upArrow->draw();
	downArrow->draw();

	for(auto it = children.begin(); it != children.end(); ++it)
	{
		(*it)->draw();
	}
}

void ScrollBar::refreshPos(float deltaPos)
{
	RendererBase* pRenderer = pDrawer->pRenderer;
	currentPos += deltaPos;
	if (occupy > 1.0f)
	{
		occupy = 1.0f;
	}
	if (occupy < 0)
	{
		occupy = 0;
	}
	if(currentPos < 0) currentPos = 0;
	if(currentPos > 1) currentPos = 1;

	float newH = rect.h * occupy;
	float newY = rect.y + currentPos * newH;
	Vertex eleVertices[36]; 

	for (int i = 0; i < 9; ++i)
	{
		Rect gridRect = grid[i];
		float left, right, top, bottom;



		if(i == TOPRIGHT || i == MIDRIGHT || i == BOTTOMRIGHT)
		{
			left = (-(float)pRenderer->screenWidth / 2) + (float)rect.x + rect.w  - edgeWidth;
		}
		else
		{
			left = (-(float)pRenderer->screenWidth / 2) + (float)rect.x + (float)gridRect.x ;
		}



		if(i == TOPMID || i == MIDMID || i == BOTTOMMID)
		{
			//mid grid , draw as the xml says
			right = left + rect.w  - 2 * edgeWidth;
		}
		else
		{
			right = left + (float)gridRect.w ;
		}

		if (i > MIDRIGHT && i <= BOTTOMRIGHT)
		{
			//bottom 3 grid
			top = (float)pRenderer->screenHeight / 2 - (float)newY - (newH - edgeHeight);
		}
		else
		{
			top = (float)pRenderer->screenHeight / 2 - (float)newY -  (float)gridRect.y;
		}

		if(i > TOPRIGHT && i <= MIDRIGHT)
		{
			bottom = top - (newH - 2 * edgeHeight) ;
		}
		else
		{
			bottom = top - (float)gridRect.h ;
		}





		eleVertices[i*4+0].pos = vec3f(left, top, 0.0f);  // Top left.
		eleVertices[i*4+0].coord = uv[4];
		eleVertices[i*4+0].coord.x += gridRect.x/512.0f;
		eleVertices[i*4+0].coord.y += gridRect.y/512.0f;

		eleVertices[i*4+1].pos = vec3f(left, bottom, 0.0f);  // Bottom left.
		eleVertices[i*4+1].coord = eleVertices[i*4+0].coord;
		eleVertices[i*4+1].coord.y += gridRect.h/512.0f;

		eleVertices[i*4+2].pos = vec3f(right, bottom, 0.0f);  // Bottom right.
		eleVertices[i*4+2].coord = eleVertices[i*4+0].coord;
		eleVertices[i*4+2].coord.x += gridRect.w/512.0f;
		eleVertices[i*4+2].coord.y += gridRect.h/512.0f;

		eleVertices[i*4+3].pos = vec3f(right, top, 0.0f);  // Top right.
		eleVertices[i*4+3].coord = eleVertices[i*4+0].coord;
		eleVertices[i*4+3].coord.x += gridRect.w/512.0f;




	}
	std::vector<Vertex>* vertices = pDrawer->playout->vertices;
	memcpy_s(&(*vertices)[frontVertexOffset],36*sizeof(Vertex),eleVertices,36*sizeof(Vertex));
	pRenderer->updateVBO(&vertices->front(),0,vertices->size(),sizeof(Vertex),pDrawer->vboId);

}

void ScrollBar::handleEvent( Event* e )
{
	switch(e->type)
	{
		case MOUSE_BUTTON_RELEASE:
			//check inside
			upArrow->handleEvent(e);
			downArrow->handleEvent(e);
			isDraging = false;
			break;
		case MOUSE_BUTTON_DOWN:
			if(isInside(e))
				isDraging = true;
			break;
		case MOUSE_DRAG:
			if(isDraging)
			{
				vec3f delta = static_cast<MouseEvent*>(e)->deltaMove;
				refreshPos(-delta.x/30);
			}
			break;
	}

}

void ScrollBar::doSomething(std::vector<info>& i, std::string& funcName)
{
	if(funcName == std::string("refreshPos"))
			refreshPos(i.front().f);
}

}


